<template>
  <div class="homepage">
    <div class="banner">
      <div class="introduction">
        <div>Game Flex Match</div>
        <div>打造业内领先的游戏服务托管解决方案</div>
      </div>
      <img src="@/assets/images/GameFlexMatch.jpg" />
    </div>
    <div class="userMsg">
      <div class="message">
        <span class="label">租户名称:</span>
        <span>{{ appStore.userStore.origin_domain_name }}</span>
        <span class="label">项目ID:</span>
        <span>{{ appStore.userStore.ori_project_id }}</span>
        <span class="label">租户标识:</span>
        <span>{{ appStore.userStore.project_id }}</span>
      </div>
    </div>
    <div class="fleetStatistic">
      <div class="Statistic" @click="fleetMsg">
        <div class="number">
          <div>Fleet总数量</div>
          <div>{{ fleetStatistic.fleet }}</div>
        </div>
        <img src="@/assets/images/1.png" />
      </div>
      <div class="Statistic" @click="instanceMsg">
        <div class="number">
          <div>实例总数量</div>
          <div>{{ fleetStatistic.instance }}</div>
        </div>
        <img src="@/assets/images/2.png" />
      </div>
      <div class="Statistic" @click="processMsg">
        <div class="number">
          <div>进程总数量</div>
          <div>{{ fleetStatistic.process }}</div>
        </div>
        <img src="@/assets/images/3.png" />
      </div>
      <div class="Statistic" @click="sessionMsg">
        <div class="number">
          <div>会话总数量</div>
          <div>{{ fleetStatistic.session }}</div>
        </div>
        <img src="@/assets/images/4.png" />
      </div>
    </div>
    <div class="fleetMsg">
      <div class="label">
        <span>Fleet信息一览</span>
        <div></div>
        <span class="legend">实例</span>
        <div></div>
        <span class="legend">进程</span>
        <div></div>
        <span class="legend">会话</span>
      </div>
      <el-scrollbar>
        <div class="eachChart" v-for="index in dataNumber" :key="index">
          <el-tooltip v-if="showtooltip[index - 1]" effect="dark" :content="titleset[index - 1]" placement="top">
            <div class="title">
              {{ showtitleset[index - 1] }}
            </div>
          </el-tooltip>
          <div v-if="!showtooltip[index - 1]" class="title">
            {{ showtitleset[index - 1] }}
          </div>
          <div v-if="dataNumber > 8" :id="'chart' + (index - 1).toString()" style="width: 180px; height: 200px" @click="getFleetDetail(index)"></div>
          <div v-else-if="dataNumber <= 4" :id="'chart' + (index - 1).toString()" style="width: 385px; height: 200px" @click="getFleetDetail(index)"></div>
          <div
            class="chartType"
            v-else
            :id="'chart' + (index - 1).toString()"
            :style="{ width: 1620 / dataNumber - 20 + 'px', height: '200px' }"
            @click="getFleetDetail(index)"
          ></div>
        </div>
      </el-scrollbar>
    </div>
    <div class="fleetState">
      <div class="label">
        <span>Fleet运行状态一览</span>
      </div>

      <div class="fleetTable">
        <div class="placeholder" v-loading="loading" v-if="loading"></div>
        <el-table
          v-else
          :data="fleetData.data"
          style="width: 100%"
          :header-cell-style="{ background: '#f4f5f8', color: '#252b3a' }"
          :border="true"
          @sort-change="sortChange"
        >
          <el-table-column>
            <template #header>
              <div class="select-box">
                <el-select v-model="fleet" class="m-2 fleet" multiple collapse-tags collapse-tags-tooltip placeholder="请选择Fleet" @change="selectChange">
                  <el-option v-for="i in fleet_options" :key="i.value" :label="i.label" :value="i.value">
                    <div class="fleetLabel">{{ i.label }}</div>
                    <div class="fleetValue">{{ i.value }}</div>
                  </el-option>
                </el-select>
              </div>
            </template>
            <el-table-column label="名称/ID" class-name="elcell" min-width="300">
              <template #default="scope">
                <div style="width: 230px">
                  <div class="toDetails" @click="showDetails(scope.row.fleet_id, scope.row.name)">
                    {{ scope.row.name }}
                  </div>
                  <el-tooltip effect="dark" :content="scope.row.fleet_id" placement="bottom">
                    <div class="id-box">
                      {{ scope.row.fleet_id }}
                    </div>
                  </el-tooltip>
                </div>
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column label="实例" sortable="custom">
            <el-table-column label="激活" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'instance_Active')">
                  {{ scope.row.instance_Active }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.instance_Active + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#1985fd'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="激活中" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'instance_Activating')">
                  {{ scope.row.instance_Activating }}
                </div>
                <div
                  class="first"
                  :style="{
                    width: ((scope.row.instance_Activating + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#0FC6A4'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="异常" min-width="180">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'instance_Error')">
                  {{ scope.row.instance_Error }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.instance_Error + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#FF4747'
                  }"
                ></div>
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column label="进程" sortable="custom">
            <el-table-column label="活跃" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'process_active')">
                  {{ scope.row.process_active }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.process_active + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#1985fd'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="正在激活" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'process_activating')">
                  {{ scope.row.process_activating }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.process_activating + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#0fc6a4'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="正在被终止" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'process_terminating')">
                  {{ scope.row.process_terminating }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.process_terminating + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#FFCE3A'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="异常" min-width="180">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'process_error')">
                  {{ scope.row.process_error }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.process_error + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#FF4747'
                  }"
                ></div>
              </template> </el-table-column
          ></el-table-column>
          <el-table-column label="会话" sortable="custom">
            <el-table-column label="活跃" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'session_active')">
                  {{ scope.row.session_active }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.session_active + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#1985fd'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="正在激活" min-width="128">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'session_activating')">
                  {{ scope.row.session_activating }}
                </div>
                <div
                  :style="{
                    width: ((scope.row.session_activating + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#0FC6A4'
                  }"
                ></div>
              </template>
            </el-table-column>
            <el-table-column label="异常" min-width="180">
              <template #default="scope">
                <div class="number" @click="showOthersDetails(scope.row.fleet_id, 'session_error')">
                  {{ scope.row.session_error }}
                </div>
                <div
                  class="first"
                  :style="{
                    width: ((scope.row.session_error + 1) / maxState) * 128 + 'px',
                    height: '2px',
                    background: '#FF4747'
                  }"
                ></div>
              </template> </el-table-column
          ></el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
  @import '@/assets/scss/dropdownBox.scss';
  .homepage {
    .placeholder {
      height: 318px;
    }
    .banner {
      display: flex;
      align-items: center;
      height: 240px;
      background-color: #33529e;
      background-repeat: no-repeat;
      background-size: cover;
      justify-content: space-between;
      position: relative;
      .introduction {
        color: #ffffff;
        margin-left: 60px;
        position: absolute;
        div:nth-child(1) {
          font-size: 36px;
          font-weight: bold;
        }
        div:nth-child(2) {
          font-size: 20px;
          margin-top: 24px;
        }
      }
      img {
        width: 100%;
        height: 100%;
        margin-right: 10px;
      }
    }
    .userMsg {
      height: 60px;
      background: #ffffff;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding-left: 30px;
      padding-right: 30px;
      border: 1px solid #e0e2e9;
      .message {
        .label {
          font-size: 14px;
          font-weight: bold;
          margin-right: 5px;
        }
        span:nth-child(2n) {
          margin-right: 60px;
          font-size: 14px;
        }
      }
    }

    .fleetStatistic {
      display: flex;
      justify-content: space-between;
      margin-top: 20px;
      gap: 20px;
      .Statistic:hover {
        box-shadow: 0px 5px 5px 0px rgba(50, 92, 176, 0.1);
      }
      .Statistic {
        display: flex;
        height: 100px;
        width: 25%;
        background-color: #ffffff;
        border: 1px solid #e0e2e9;
        cursor: pointer;
        img {
          margin-left: 120px;
        }
        .number {
          margin-left: 30px;
          margin-top: 26px;
          div:nth-child(1) {
            font-size: 14px;
          }
          div:nth-child(2) {
            margin-top: 10px;
            font-weight: bold;
            font-size: 24px;
            color: #325cb0;
          }
        }
      }
    }

    .fleetMsg {
      border: 1px solid #e0e2e9;
      padding-top: 30px;
      height: 340px;
      background-color: #ffffff;
      margin-top: 20px;
      box-sizing: border-box;
      .label {
        font-size: 16px;
        font-weight: bold;
        margin-bottom: 20px;
        display: flex;
        align-items: center;
        margin-left: 30px;
        .legend {
          margin-right: 20px;
          font-size: 12px;
          font-weight: normal;
        }
        div {
          height: 12px;
          width: 12px;
          margin-right: 4px;
        }
        div:nth-child(2) {
          background-color: #1985fd;
          margin-left: 47px;
        }
        div:nth-child(4) {
          background-color: #0fc6a4;
        }
        div:nth-child(6) {
          background-color: #ffce3a;
        }
      }
      .el-scrollbar {
        height: 270px;
      }
      :deep(.el-scrollbar__view) {
        display: flex;
        gap: 20px;
        margin-left: 30px;
        margin-right: 24px;
      }
      .eachChart {
        border: 1px solid #e0e2e9;
        border-radius: 2px;
        :hover {
          cursor: pointer;
        }
        .title {
          margin-top: 26px;
          text-align: center;
          font-weight: normal;
          font-size: 14px;
          color: #252b3a;
        }
      }
      .eachChart:hover {
        cursor: pointer;
        box-shadow: 0px 5px 5px 0px rgba(50, 92, 176, 0.1);
      }
    }

    .fleetState {
      border: 1px solid #e0e2e9;
      padding-top: 30px;
      background-color: #ffffff;
      margin-top: 20px;
      .label {
        font-size: 16px;
        font-weight: bold;
        margin-bottom: 20px;
        display: flex;
        align-items: center;
        margin-left: 30px;
      }
      .select-box {
        display: flex;
        align-items: center;
        font-size: 14px;
        font-weight: bold;
        color: #1d1d1f;
      }
      .fleetTable {
        padding: 14px 30px 30px 30px;
        border-radius: 2px;
        :deep(.el-table) {
          border-radius: 2px;
          font-size: 14px;
          color: $text-color;
          tr {
            border-color: $border-color;
            height: 78px;
          }
          thead > tr:first-child {
            height: 36px;
          }
          .el-table__cell {
            border-right: none;
            font-weight: normal;
          }
        }
        :deep(.toDetails) {
          color: $main-color;
          cursor: pointer;
          width: 100%;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        :deep(.toDetails:hover) {
          text-decoration: underline;
        }
        :deep(.id-box) {
          width: 100%;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        :deep(.cell) {
          padding: 0 30px 0 20px;
        }
        .number {
          margin-bottom: 5px;
          cursor: pointer;
        }
        .number:hover {
          color: #325cb0;
        }
      }
    }
  }
  .el-select-dropdown.is-multiple .el-select-dropdown__item.selected {
    color: $main-color;
  }
</style>
<script lang="ts" setup>
  import appStore from '@/store'
  import Vue, { reactive, ref, nextTick, onBeforeUnmount, onMounted } from 'vue'
  import router from '@/router'
  import Monitor, { ProcessParamType } from '@/api/Monitor'
  import userService from '@/api/userService'
  import * as echarts from 'echarts'
  import _cloneDeep from 'lodash/cloneDeep'
  import _debounce from 'lodash/debounce'
  let loading = ref(false)
  let fleet = ref([])
  interface dimension {
    name: string
    fleet_id: string
    instance_Active: number
    instance_Activating: number
    instance_Error: number
    process_active: number
    process_activating: number
    process_terminating: number
    process_error: number
    session_active: number
    session_activating: number
    session_error: number
    [key: string]: string | number
  }
  let fleetData: { data: dimension[] } = reactive({ data: [] })
  let fleetAllData: dimension[] = []
  let fleetStatistic = reactive({
    fleet: 0,
    instance: 0,
    process: 0,
    session: 0
  })
  interface optionList {
    value: string
    label: string
  }
  const fleet_options: optionList[] = reactive([])
  let orderSort = ref('')
  const getFleetParam: ProcessParamType = {
    project_id: appStore.userStore.project_id
  }
  const showDetails = (id: string, name: string) => {
    router.push({
      name: 'fleetDetails',
      params: {
        id,
        name
      }
    })
  }

  const showOthersDetails = (id: string, key: string) => {
    let health_state
    let rkey = key.split('_')
    let run = rkey[0].charAt(0).toUpperCase() + rkey[0].slice(1)
    if (key == 'instance_Active' || key == 'instance_Activating' || key == 'instance_Error') {
      health_state = rkey[1].charAt(0).toUpperCase() + rkey[1].slice(1)
    } else {
      health_state = rkey[1].toUpperCase()
    }
    router.push({
      name: 'runningState',
      query: {
        id,
        run,
        health_state
      }
    })
  }

  const fleetMsg = () => {
    router.push({ name: 'runningState' })
  }

  const instanceMsg = () => {
    let run = 'Instance'
    router.push({ name: 'runningState', query: { run } })
  }

  const processMsg = () => {
    let run = 'Process'
    router.push({ name: 'runningState', query: { run } })
  }

  const sessionMsg = () => {
    let run = 'Session'
    router.push({ name: 'runningState', query: { run } })
  }

  let dataset: { x: string; y: number }[][] = [[]]
  let titleset: string[] = []
  let showtitleset = ref<string[]>([])
  let dataNumber = ref(0)
  let maxy: number = 0
  const getdataset = (data: any) => {
    titleset = []
    dataset = [[]]
    data.forEach((item: any) => {
      titleset.push(item.fleet_name)
      dataset.push([
        {
          x: 'instance',
          y: item.instance_count
        },
        {
          x: 'process',
          y: item.process_count
        },
        {
          x: 'session',
          y: item.server_session_count
        }
      ])
      maxy = Math.max(item.instance_count, item.process_count, item.server_session_count, maxy)
    })
    dataset.splice(0, 1)
  }

  let activeFleets: any
  const filterFleet = () => {
    let fleet_ids: string[] = []
    fleet.value.forEach((item: string) => {
      fleet_ids.push(item)
    })
    let max = 0
    fleetAllData.forEach((item) => {
      Object.keys(item).forEach((key) => {
        if (typeof item[key] === 'number') {
          max > item[key] ? '' : (max = item[key] as number)
        }
      })
    })
    maxState.value = max
    let temp = fleetAllData.filter((obj: any) => fleet_ids.indexOf(obj.fleet_id) != -1)
    if (fleet_ids.length > 0) {
      fleetData.data.length = 0
      fleetData.data.push(...temp)
    } else {
      fleetData.data.length = 0
      fleetData.data.push(...fleetAllData)
    }
    loading.value = false
  }
  const setFleetOptions = (name: string, fleet_id: string) => {
    fleet_options.push({
      label: `${name}`,
      value: fleet_id
    })
  }
  const computeStatistic = (data: any) => {
    fleetStatistic.instance = data.reduce((c: any, R: any) => c + R.instance_count, 0)
    fleetStatistic.process = data.reduce((c: any, R: any) => c + R.process_count, 0)
    fleetStatistic.session = data.reduce((c: any, R: any) => c + R.server_session_count, 0)
  }
  let myChartList: echarts.ECharts[] = []
  let chartOptionList: { [key: string]: any }[] = []
  let chartOption = {
    title: {
      show: false
    },
    tooltip: { show: false },
    dataset: {
      dimensions: ['x', 'y'],
      source: [
        { x: 'instance', y: 1 },
        { x: 'process', y: 50 },
        { x: 'session', y: 20 }
      ]
    },
    xAxis: { show: false, type: 'category' },
    yAxis: { show: false },
    series: [
      {
        type: 'bar',
        barWidth: 10,
        barGap: 30,
        label: {
          show: true,
          position: 'top'
        },
        textStyle: {
          color: '#8a8e99',
          fontSize: 12
        },
        itemStyle: {
          borderRadius: [2, 2, 0, 0]
        }
      }
    ],
    colorBy: 'data',
    color: ['#1985FD', '#0FC6A4', '#FFCE3A'],
    grid: {
      bottom: 30,
      top: 28
    }
  }
  let showtooltip = ref<boolean[]>([])
  const initEcharts = () => {
    let newPromise = new Promise<void>((resolve) => {
      resolve()
    })
    newPromise.then(async () => {
      let width = 10
      let gap = 30
      let maxTextLength = 20
      let textLength = 6
      if (4 < dataset.length && dataset.length <= 8) {
        width = dataset.length * -5 + 50
        gap = dataset.length * -7.5 + 90
        maxTextLength = dataset.length * -7.5 + 80
        textLength = dataset.length * -2.25 + 24
      } else if (dataset.length <= 4) {
        width = 30
        gap = 60
        maxTextLength = 50
        textLength = 15
      }
      await nextTick()
      let title = ''
      myChartList.length = 0

      dataset.forEach((item, index) => {
        myChartList.push(echarts.init(document.getElementById('chart' + index.toString()) as HTMLElement))
        chartOptionList.push(JSON.parse(JSON.stringify(chartOption)))
        chartOptionList[index].dataset.source = item

        if (titleset[index].length > maxTextLength) {
          title = titleset[index].slice(0, textLength) + '......' + titleset[index].slice(-textLength)
          showtooltip.value.push(true)
          showtitleset.value.push(title)
        } else {
          title = titleset[index]
          showtooltip.value.push(false)
          showtitleset.value.push(title)
        }
        chartOptionList[index].series[0].barWidth = width
        chartOptionList[index].series[0].barGap = gap
        myChartList[index].setOption(chartOptionList[index] as any)
      })
    })
  }
  window.addEventListener('resize', function () {
    myChartList.forEach((item) => {
      item.resize()
    })
  })

  const getFleetDetail = (index: number) => {
    let id = activeFleets[index - 1].fleet_id
    let name = activeFleets[index - 1].name
    router.push({ name: 'fleetDetails', params: { id, name } })
  }

  let maxState = ref(0)

  const selectChange = () => {
    filterFleet()
  }

  const getHomePage = async () => {
    let flag = false
    let obj = _cloneDeep(getFleetParam)
    orderSort.value ? (obj.order_by = orderSort.value) : ''
    let res = await Monitor.getHomePage(obj)
    if (res?.status === 200) {
      fleetStatistic.fleet = res.data.total_count
      computeStatistic(res.data.fleets)
      activeFleets = res.data.fleets.filter((fleet: any) => fleet.state == 'ACTIVE')
      dataNumber.value = activeFleets.length
      flag = true
    }
    if (flag) {
      setTableDate(activeFleets)
      getdataset(activeFleets)
      initEcharts()
    }
  }
  getHomePage()
  const setTableDate = async (arr: any[]) => {
    fleet_options.length = 0
    fleetAllData.length = 0
    arr.forEach((item) => {
      setTableItem(item)
    })
  }
  const setTableItem = (item: any) => {
    let newItem: dimension = {
      name: '',
      fleet_id: '',
      instance_Active: 0,
      instance_Activating: 0,
      instance_Error: 0,
      process_active: 0,
      process_activating: 0,
      process_terminating: 0,
      process_error: 0,
      session_active: 0,
      session_activating: 0,
      session_error: 0
    }
    newItem.fleet_id = item.fleet_id
    newItem.name = item.fleet_name
    item.app_processes.forEach((pro: { state: string; count: string | number }) => {
      let temp = 'process_' + pro.state.toLowerCase()
      newItem[temp] = pro.count
    })
    item.instances.forEach((ins: { state: string; count: string | number }) => {
      let temp = ins.state
      newItem['instance_' + temp] = ins.count
    })
    item.server_sessions.forEach((ser: { state: string; count: string | number }) => {
      let temp = ser.state.toLowerCase()
      newItem['session_' + temp] = ser.count
    })
    setFleetOptions(item.fleet_name, item.fleet_id)
    fleetAllData.push(newItem)
    filterFleet()
    loading.value = false
  }
  const timer = ref<any>(null)
  const countdown = ref(0)
  const autoRefreshTime = ref(60)
  onMounted(() => {
    timer.value = window.setInterval(() => {
      if (countdown.value < autoRefreshTime.value) {
        countdown.value = countdown.value + 1
        if (countdown.value === autoRefreshTime.value) {
          refresh()
        }
      }
    }, 1000)
  })
  const refresh = () => {
    getHomePage()
    setTimeout(() => {
      countdown.value = 0
    }, 2000)
  }
  onBeforeUnmount(() => {
    window.clearInterval(timer.value)
  })
  const sortChange = (column: { order: any; column: any }) => {
    let { order } = column
    let { label } = column.column
    let orderBy = ''
    switch (label) {
      case '实例':
        order == 'ascending' ? (orderBy = 'instance_count') : (orderBy = '-instance_count')
        break
      case '进程':
        order == 'ascending' ? (orderBy = 'process_count') : (orderBy = '-process_count')
        break
      default:
        order == 'ascending' ? (orderBy = 'server_session_count') : (orderBy = '-server_session_count')
        break
    }
    orderSort.value == orderBy ? (orderSort.value = '') : (orderSort.value = orderBy)
    changeSort()
  }
  const changeSort = _debounce(() => {
    getHomePage()
  }, 500)
</script>
